package threadPoolDemo;

import org.apache.log4j.Logger;

import java.util.concurrent.SynchronousQueue;

/**
 * @author Ajie
 * @date 7/15/21
 * @function
 *     原文链接：https://blog.csdn.net/yanyan19880509/article/details/52562039
 *
 * 结论：
 * SynchronousQueue 会阻塞在 queue.put()，当有任务没有被消费时 queue.take()。
 * Adds the specified element to this queue, waiting if necessary for
 * another thread to receive it.
 *
 *
 * 从结果可以看出，put线程执行queue.put(1) 后就被阻塞了，!!!!
 * 只有take线程进行了消费，put线程才可以返回。可以认为这是一种线程与线程间一对一传递消息的模型。
 */
public class SynchronousQueueDemo {
    private static final Logger logger = Logger.getLogger(SynchronousQueueDemo.class);

    public static void main(String[] args) throws InterruptedException {
        final SynchronousQueue<Integer> queue = new SynchronousQueue<Integer>();

        Thread putThread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("put thread start");
                try {
                    queue.put(1);
                    logger.info("run: put 1 end");
                    logger.info("run: put 2 start");

                    queue.put(2);

                    logger.info("run: put 2 end");
                } catch (InterruptedException e) {
                }
                System.out.println("put thread end");
            }
        });

        Thread takeThread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("take thread start. next will take queue.take()");
                try {
                    Integer take = queue.take();
                    System.out.println("take from putThread over: " + take);
                } catch (InterruptedException e) {
                }
                System.out.println("take thread end");
            }
        });

        putThread.start();
        System.out.println("taks start sleep:main:2000");
        Thread.sleep(2000);
        takeThread.start();

        Thread.sleep(2000);
        logger.info("main: take 2 start");
        queue.take();
    }
}
